package sg.edu.nus.iss.cerberus.actions;

import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.internal.core.PackageFragment;
import org.eclipse.jdt.internal.core.PackageFragmentRoot;
import org.eclipse.jdt.internal.core.SourceType;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import sg.edu.nus.iss.cerberus.util.CerberusConstants;

@SuppressWarnings("restriction")
public class FolderCreation {
	
	private IStructuredSelection iSelection;
	private IProject project;
	private String packageName = CerberusConstants.TEST_FOLDER_NAME;
	private IPackageFragment fragment;
	private IPackageFragmentRoot fragmentRoot;
	
		
	public FolderCreation(IStructuredSelection iSelection) throws CoreException {
		this.iSelection = iSelection;
		fragment = null;
		fragmentRoot = null;
		prepareWorkspace(this.iSelection);
	}
	
	private void setPackageName(String packageName){
		this.packageName = packageName;
	}
	
	private void setProjectName(IJavaProject iJavaProject){
		this.project =  iJavaProject.getProject();
	}

	public IPackageFragment getPackageFrag(){
		return this.fragment;
	}
	
	public IPackageFragmentRoot getPackageFragRoot(){
		return this.fragmentRoot;
	}
	
	public void createTestPackage() throws CoreException {

		IJavaProject iJavaProject = JavaCore.create(project);
		IFolder folder = project.getFolder(CerberusConstants.TEST_FOLDER_NAME);
		IPath path = folder.getFullPath();
				
		fragmentRoot = iJavaProject.findPackageFragmentRoot(path);
		fragment = fragmentRoot.getPackageFragment(this.packageName);
		
		if(!(fragment.exists())) {
			fragmentRoot.createPackageFragment(packageName, true,
				new NullProgressMonitor());
		IFolder f = ResourcesPlugin.getWorkspace().getRoot().getFolder(path);
		f.refreshLocal(IResource.DEPTH_INFINITE, null);
		}
	}
	
	public IFolder createTestFolder() throws CoreException {

		IJavaProject iJavaProject = JavaCore.create(project);
		IFolder folder = project.getFolder(CerberusConstants.TEST_FOLDER_NAME);
		IPath testFolderPath = folder.getFullPath();
		

		if (!folder.exists()) {

			folder.create(false, true, null);
			folder.refreshLocal(IResource.DEPTH_INFINITE, null);

			IClasspathEntry entry = JavaCore.newSourceEntry(testFolderPath);
			IClasspathEntry[] entries = iJavaProject.getRawClasspath();
			IClasspathEntry[] newEntries = new IClasspathEntry[entries.length + 1];
			
			System.arraycopy(entries, 0, newEntries, 0, entries.length);
			newEntries[newEntries.length - 1] = entry;
			iJavaProject.setRawClasspath(newEntries, new NullProgressMonitor());

			folder.refreshLocal(IResource.DEPTH_INFINITE, null);
		}
		
		return folder;
	}
		
	private void prepareWorkspace(IStructuredSelection iSelect) throws CoreException{
	  	    	
		if(iSelect instanceof StructuredSelection){
    		Object obj = iSelect.getFirstElement();	
    		
    		if(obj instanceof SourceType){
    		    ICompilationUnit cu = ((SourceType) obj).getCompilationUnit();
    			setProjectName(cu.getJavaProject());
    			setPackageName(cu.getParent().getElementName());
    		}
    		if(obj instanceof PackageFragment){
    			IPackageFragment ipf = (IPackageFragment)obj;
    			setProjectName(ipf.getJavaProject());
    			setPackageName(ipf.getElementName());
      		}
    		if(obj instanceof PackageFragmentRoot){
    			IPackageFragmentRoot ipfr = (IPackageFragmentRoot)obj;
    			setProjectName(ipfr.getJavaProject());
    			setPackageName(ipfr.getElementName());
    		}
    	}
		
		if(this.project != null ){
		JUnitCheck junitCheck = new JUnitCheck(JavaCore.create(project));
		if(!junitCheck.checkJUnitInBuildPath()){
			junitCheck.addJUnitToBuildPath();
		}
		}
	}
}